// utils/request.js
import config from '@/static/config.js';
import { getDeviceId } from '@/utils/device'; // 导入设备号工具

// 防止重复弹出授权弹窗的标志位
let isShowingAuthModal = false;
/**
 * 封装UniApp请求，统一处理：
 * - Token自动注入请求头
 * - 设备号(d-id)自动注入请求头
 * - 401未登录自动跳转
 * - 业务错误统一提示
 */

const request = (options) => {
    // ... (1. 请求前的逻辑保持不变)
    const token = uni.getStorageSync('token');
    const deviceId = getDeviceId();
    const header = {
        'Content-Type': 'application/json',
        'd-id': deviceId,
        ...options.header
    };
    if (token) {
        header.Authorization = token;
    }

    // 2. 发起UniApp请求
    return new Promise((resolve, reject) => {
        uni.request({
            url: `${config.baseUrl}/${options.url}`,
            method: options.method || 'GET',
            data: options.data || {},
            header,
            // 3. 响应拦截：统一处理业务逻辑
            success: (res) => {
                // 注意：这里的 res.statusCode 是 HTTP 状态码 (如 200, 404, 500)
                // res.data 才是后端返回的 JSON 对象

                // 如果 HTTP 请求本身失败 (如 404, 500)，直接 reject
                if (res.statusCode < 200 || res.statusCode >= 300) {
                    return reject(new Error(`HTTP错误: ${res.statusCode}`));
                }

                const { code, msg, data } = res.data;

                // 401未登录逻辑保留，因为这是需要全局处理的特殊情况
                if (code === 401) {
                    uni.removeStorageSync('token');
                    const currentPage = getCurrentPages().pop();
                    if (currentPage.route !== 'pages/login/index') {
                        uni.showToast({ title: '登录已过期，请重新登录', icon: 'none' });
                        setTimeout(() => {
                            uni.reLaunch({ url: '/pages/login/index' });
                        }, 1500);
                    }
                    // 对于401，拒绝 Promise，因为它中断了当前流程
                    return reject(new Error('未登录或登录已过期'));
                }

                // 【核心修改】对于其他所有业务码，都 resolve 返回完整的 res.data
                // 让调用方自己判断 code 是 200 还是其他
                resolve(res.data);

            },
            fail: (err) => {
                // fail 回调只处理真正的网络问题 (如 DNS解析失败, 连接超时)
                // 这里的 reject 会被调用方的 catch 捕获，显示“网络异常”
                reject(err);
            }
        });
    });
}


/**
 * 【原始响应】请求封装
 * 特点：
 * - 注入Token和设备号(d-id)
 * - 处理401未登录
 * - 不校验业务code，直接返回完整的响应数据
 * - 适用于流式数据、二进制文件等非标准JSON响应
 */
const requestRaw = (options) => {
    // 1. 注入通用请求头
    const token = uni.getStorageSync('token');
    const deviceId = getDeviceId();
    const header = {
        'Content-Type': 'application/json',
        'd-id': deviceId,
        ...options.header
    };
    if (token) {
        header.Authorization = token;
    }

    return new Promise((resolve, reject) => {
        uni.request({
            url: `${config.baseUrl}/${options.url}`,
            method: options.method || 'GET',
            data: options.data || {},
            header,
            responseType: options.responseType, // 支持 'arraybuffer', 'blob' 等
            success: (res) => {
                console.log("请求地址:"+options.url+ ", 返回值:"+res)
                // 2. 仅处理HTTP层面的错误和401
                if (res.statusCode !== 200) {
                    // 对于HTTP 4xx/5xx错误，直接reject
                    const errorMsg = `请求失败 [${res.statusCode}]`;
                    uni.showToast({ title: errorMsg, icon: 'none' });
                    reject(new Error(errorMsg));
                    return;
                }

                // 3. 处理业务层面的401未登录
                // 尝试解析JSON，以检查是否是标准的401响应
                try {
                    // 只有当响应是JSON时，才进行code检查
                    if (typeof res.data === 'string' && res.data.trim().startsWith('{')) {
                        const parsedData = JSON.parse(res.data);
                        if (parsedData.code === 401) {
                            uni.removeStorageSync('token');
                            const currentPage = getCurrentPages().pop();
                            if (currentPage.route !== 'pages/login/index') {
                                uni.showToast({ title: '登录已过期，请重新登录', icon: 'none', duration: 3000 });
                                setTimeout(() => {
                                    uni.reLaunch({ url: '/pages/login/index' });
                                }, 3000);
                            }
                            reject(new Error('未登录或登录已过期'));
                            return;
                        }
                    }
                } catch (e) {
                    // 如果解析JSON失败，说明不是标准API响应，忽略即可
                }

                // 4. 【核心】直接返回完整的响应数据，不做任何业务code校验
                // 对于流式接口，res.data将是ArrayBuffer
                // 对于普通JSON接口，res.data将是Object或String
                resolve(res.data);
            },
            fail: (err) => {
                uni.showToast({ title: '网络异常，请检查网络', icon: 'none' });
                reject(err);
            }
        });
    });
};

/**
 * 文件上传封装
 * @param {string} url - 上传接口的相对路径 (e.g., 'agent/file/upload')
 * @param {string} filePath - 要上传的文件的本地临时文件路径
 * @param {string} name - 文件对应的 key，后端通过这个 key 获取文件 (e.g., 'files')
 * @param {object} [formData] - 额外的表单数据
 */
const uploadFile = (url, filePath, name, formData = {}) => {
    const token = uni.getStorageSync('token');
    const deviceId = getDeviceId();
    const header = {
        'd-id': deviceId,
    };
    // `uni.uploadFile` 会自动设置 'Content-Type': 'multipart/form-data'，这里无需手动添加
    if (token) {
        header.Authorization = token;
    }

    return new Promise((resolve, reject) => {
        uni.uploadFile({
            url: `${config.baseUrl}/${url}`, // 拼接完整URL
            filePath: filePath,
            name: name,
            formData: formData,
            header: header,
            success: (uploadRes) => {
                // 注意：uploadRes.data 是一个 JSON 字符串，需要解析
                const data = JSON.parse(uploadRes.data);
                const { code, msg } = data;

                // 复用 401 未登录逻辑
                if (code === 401) {
                    uni.removeStorageSync('token');
                    const currentPage = getCurrentPages().pop();
                    if (currentPage.route !== 'pages/login/index') {
                        uni.showToast({ title: '登录已过期，请重新登录', icon: 'none', duration: 3000 });
                        setTimeout(() => {
                            uni.reLaunch({ url: '/pages/login/index' });
                        }, 3000);
                    }
                    reject(new Error('未登录或登录已过期'));
                    return;
                }

                if (code === 200) {
                    // 假设后端直接返回了图片URL或URL列表
                    resolve(data.data);
                } else {
                    // 业务错误，例如文件过大、格式不正确等
                    uni.showToast({ title: msg || '文件上传失败', icon: 'none' });
                    reject(new Error(msg || '文件上传失败'));
                }
            },
            fail: (err) => {
                // 网络错误，例如跨域、服务器未启动等
                uni.showToast({ title: '上传失败，请检查网络连接', icon: 'none' });
                reject(err);
            }
        });
    });
};


// 导出方法
export default {
    get(url, data = {}, header = {}) {
        return request({ url, method: 'GET', data, header });
    },
    post(url, data = {}, header = {}) {
        return request({ url, method: 'POST', data, header });
    },
    put(url, data = {}, header = {}) {
        return request({ url, method: 'PUT', data, header });
    },
    getRaw(url, data = {}, header = {}, config = {}) {
        return requestRaw({ url, method: 'GET', data, header, ...config });
    },
    postRaw(url, data = {}, header = {}, config = {}) {
        return requestRaw({ url, method: 'POST', data, header, ...config });
    },
    putRaw(url, data = {}, header = {}, config = {}) {
        return requestRaw({ url, method: 'PUT', data, header, ...config });
    },
    upload: uploadFile // 导出文件上传方法
};